<?php

namespace App\Http\Controllers\Quiz;

use App\Morefun\Quiz\OptionService;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Responses\Code;
use App\Contracts\Repositories\QuizRepository as QuizRepositoryContract;
use App\Morefun\Quiz\QuizService;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;

class ApiController extends Controller
{
    protected $quizzes;

    public function __construct(QuizRepositoryContract $quizzes)
    {
        $this->quizzes = $quizzes;
    }

    public function many(Request $request, QuizService $service)
    {
        $type = $request->get('type');
        $keyword = $request->get('keyword');
        $perPage = $request->get('per_page', 10);
        $activity_id = $request->get('activity_id');

        $quizzes = $service->findWithPaginate(
            $perPage,
            $keyword,
            compact('type', 'activity_id')
        );

        foreach ($quizzes as $quiz) {
            $quiz->setAttribute('required', $quiz->validations['required']);
        }

        return response()->success($quizzes);
    }

    public function store(Request $request, OptionService $option)
    {
        $input = $request->json()->all();
        $validator = Validator::make($input, [
            'activity_id' => 'required',
            'type' => 'required|integer',
            'title' => 'required|max:255',
            'required' => 'required|boolean',
            'linked' => 'required|boolean',
            'links' => 'array',
            'links.id' => 'required_if:linked,1',
            'links.option_ids' => 'array',
            'options' => 'array',
        ]);

        if ($validator->fails()) {
            return response()->failed(
                Arr::first($validator->errors()->all()),
                Code::INVALID_REQUEST
            );
        }

        Arr::set($input, 'validations', ['required' => Arr::get($input, 'required', false)]);

        if (Arr::get($input, 'linked')) {
            $configurations = [
                'linked' => true,
                'link_id' => Arr::get($input, 'links.id'),
                'link_option_ids' => Arr::get($input, 'links.option_ids'),
            ];
        } else {
            $configurations = ['linked' => false];
        }

        Arr::set($input, 'configurations', $configurations);

        $id = DB::transaction(function () use ($input, $option) {
            $id = $this->quizzes->create($input);
            $option->batchBind($id, Arr::get($input, 'options', []));

            return $id;
        });

        if ($id) {
            return response()->success(compact('id'));
        }

        return response()->faild();
    }

    public function types()
    {
        return response()->success(
            $this->quizzes->types()
        );
    }

    public function unlinked(Request $request, QuizService $service, $activityId)
    {
        $without = $request->get('without');

        return response()->success(
            $service->unlinked($activityId, $without)
        );
    }

    public function show($id)
    {
        $quiz = $this->quizzes->find($id);

        if (null === $quiz) {
            return response()->failed('没有找到该资源');
        }

        return response()->success($quiz);
    }

    public function update(Request $request, $id)
    {
        $input = $request->json()->all();

        $validator = Validator::make($input, [
            'type' => 'integer',
            'title' => 'max:255',
            'required' => 'boolean',
            'linked' => 'boolean',
            'links' => 'array',
            'links.id' => 'required_if:linked,1',
            'links.option_ids' => 'array',
        ]);

        if ($validator->fails()) {
            return response()->failed(
                Arr::first($validator->errors()->all()),
                Code::INVALID_REQUEST
            );
        }

        if ($this->quizzes->update($id, $input)) {
            return response()->success();
        }

        return response()->failed('更新问题失败');
    }

    public function destroy($id)
    {
        if ($this->quizzes->delete($id)) {
            return response()->success();
        }

        return response()->failed('删除失败');
    }

    public function sort(Request $request, $id)
    {
        $sort = $request->json('sort', 0);

        if ($this->quizzes->setSort($id, $sort)) {
            return response()->success();
        }

        return response()->failed('排序失败');
    }

    public function quizzes(Request $request, $id)
    {
        $perPage = $request->get('per_page', 10);

        return response()->success(
            $this->quizzes->paginateWithOptions($id, $perPage)
        );
    }

    public function byActivity($id)
    {
        return response()->success(
            $this->quizzes->findAll([['activity_id', '=', $id]], ['id', 'type', 'title'])
        );
    }
}
